/*
 * worldlines.h
 *
 *  Created on: Jan 21, 2010
 *      Author: snirgaz
 */

#ifndef WORLDLINES_H_
#define WORLDLINES_H_

#include "HelpLibs/def.h"
//#include "xml_rw.h"
#include "ParticlePos.h"
#include "HelpLibs/hdf5RW.h"
#include "EnergyData.h"
#include "SimParams.h"
#include "HelpLibs/ArrayMultiD.h"
#include "HelpLibs/RandomGen.h"
#include <algorithm>
#include "blitz/array.h"
// Cyclic coordinate array class

using namespace blitz;

typedef Array<ParticlePos, 2> ConfData;
typedef Array<Force, 2> ForceData;

typedef Array<ParticlePos, 1> ConfSlice;
typedef Array<Force, 1> ForceSlice;

void cyclic_vec(double vec, int size);
bool isInRange(double *vec, int size, double lim);

struct WorldLinesForce {

	// Total |F|^2 Energy for each Slice
	DoubleVec totalForce_;
	ForceSlice jumpForceData_;
	double totalForceJump_;
	ForceData forceData_;
	WorldLinesForce();
	WorldLinesForce(int numP, int m);
	void resize(int numP, int m);
	~WorldLinesForce();
	double calcTotalForce(int m);
	double calcTotalForceJump();
	void dumpToFile(string fileName) const;
	void dumpToFile(hdf5RW &hdf5File) const;
	void readFromFile(string fileName);
};

struct WorldLinesWorm {
	ConfData confData_; // 2D array (slice , particle number)
	IntVec Loops_;
	// Particle number of worm jump
	int wormNum_;
	// Time Slice of Worm Jumo
	int wormSlice_;
	// Position of "jump" particle
	ParticlePos jumpPos_;
	// Delta of the jump
	ParticlePos delta_;
	// Open or Closed
	OC isOpenClosed_;
	int NumP_,M_;
	WorldLinesWorm();
	WorldLinesWorm(int NumP, int M);
	~WorldLinesWorm();
	void swapLoops(int n, int m);
	int findPreviousLoop(int n) const;
	double calcEK();
	double calcEKDiff(BeadVec const & beads) const;
	// IO
	void dumpToFile(string fileName) const;
	void dumpToFile(hdf5RW &hdf5File) const;
	void readFromFile(string FileName);
	void swapData(WorldLinesWorm &WL2);
//	void updateMove(MoveParams const & movParams, OC isOpenClosed);
//	void updateSwapMove(MoveParams const & movParams);

};

struct WorldLines {

	WorldLinesWorm wlData_;
	WorldLinesForce wlForce_;
	WLEnergyData wlEnergy_;

	void init(int n, int m);
	// Get "next" particle after beta
	// Numer of beads - NumP*M*dim
	void dumpToFile(string fileName) const;
	void readFromFile(string fileName);
	// Initialize
//	void initializeRandom(string outPath, QmcRnd &qmcRnd);
	void initializeSolid(string outPath);
	void initializeSolidFixed(string outPath);
	void initializeSolidBCC(string outPath);
	void initializeSolidHCP(string outPath, string latFileInit);
//	void initializeSolidBCCVacancies(int numOfVac, string outPath,
//			QmcRnd &qmcRnd);
//	void initializeSolidBCCInterstitials(int numOfInter, string outPath,
//			QmcRnd &qmcRnd);
	void initializeSolidBCCFixedGB(string outPath, string latFileInit,
			int &numOfFixed);
	void initializeSolidBCCFixedGBFromFile(string initPath, string outPath,
			int &numOfFixed);
	void initializeFromFile(string outPath);
	// Debugs
	bool loopCheck(int step, string out_put);bool isValidConf(string out_path);
	WLEnergyData& getEnergyData();
///	void updateMove(MoveParams const &moveParams,
//			WorldLinesForce const &forceUpdate, EnergyData const &energyDiff,
//			OC isOpenClosed);
//	void updateSwapMove(MoveParams const &moveParams,
//			WorldLinesForce const &forceUpdate, EnergyData energyDiff);
};


#endif /* WorldLINES_H_ */
